﻿using NeoAPI;

public class BaumerCameraHelper:IDisposable
{
    private Cam camera;
    private bool isGrabbing = false;
    private string savePath = "H:\\CameraImages\\";
    private NeoTrace trace;
    private bool isAcquiring = false;
    public void Run()
    {
        try
        {
            // 初始化日志跟踪
            InitializeLogging();

            // 1. 获取设备列表
            var deviceList = GetDeviceList();
            if (deviceList.List.Count == 0)
            {
                Console.WriteLine("没有找到任何相机设备");
                return;
            }

            // 2. 连接默认第一个设备
            ConnectToCamera(deviceList.List[0]);

            // 3. 设置相机参数
            ConfigureCamera();

            // 4. 注册图像事件回调
            RegisterImageCallback();

            // 5. 开始采集
            StartAcquisition();

            // 采集5张图片
            for (int i = 0; i < 5; i++)
            {
                // 6. 触发采集并保存图像
                TriggerAndSaveImage(i + 1);
                Thread.Sleep(500); // 间隔500ms
            }

            // 7. 结束采集
            StopAcquisition();

            // 8. 关闭设备
            DisconnectCamera();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生错误: {ex.Message}");
            trace.Error($"程序错误: {ex.Message}");
        }
        finally
        {
            trace.Info("程序结束", "Main", "Run", this);
            trace.Dispose();
        }

        Console.WriteLine("程序结束，按任意键退出...");
        Console.ReadKey();
    }

    /// <summary>
    /// 初始化日志跟踪
    /// </summary>
    private void InitializeLogging()
    {
        trace = new NeoTrace();
        trace.SetSeverity(NeoTraceSeverity.All);

        // 启用日志文件
        string logPath = Path.Combine(savePath, "camera_log.log");
        trace.EnableLogfile(logPath);

        // 启用回调
        trace.Callback.Handler += TraceCallbackHandler;
        trace.EnableLogCallback();

        trace.Info("日志系统初始化完成", "BaumerCamera", "InitializeLogging", this);
    }

    /// <summary>
    /// 日志回调处理
    /// </summary>
    private void TraceCallbackHandler(object sender, TraceEventArgs args)
    {
        Console.WriteLine($"[TRACE] {args.Message}");
    }

    /// <summary>
    /// 获取设备列表
    /// </summary>
    private CamInfoList GetDeviceList()
    {
        trace.Info("开始扫描设备...", "BaumerCamera", "GetDeviceList", this);

        var deviceList = CamInfoList.Get();
        deviceList.Refresh();

        Console.WriteLine($"找到 {deviceList.List.Count} 台设备:");
        for (int i = 0; i < deviceList.List.Count; i++)
        {
            Console.WriteLine($"{i + 1}. {deviceList.List[i].ModelName} (SN: {deviceList.List[i].SerialNumber})");
            trace.Info($"发现设备: {deviceList.List[i].ModelName} SN:{deviceList.List[i].SerialNumber}",
                      "BaumerCamera", "GetDeviceList", this);
        }

        return deviceList;
    }

    /// <summary>
    /// 连接到相机
    /// </summary>
    private void ConnectToCamera(CamInfo deviceInfo)
    {
        try
        {
            trace.Info($"正在连接设备: {deviceInfo.ModelName} (SN: {deviceInfo.SerialNumber})",
                      "BaumerCamera", "ConnectToCamera", this);

            camera = new Cam();
            camera.Connect(deviceInfo.ModelName);

            if (camera.IsConnected)
            {
                Console.WriteLine("连接成功");
                Console.WriteLine($"设备信息: {camera.f.DeviceVendorName} {camera.f.DeviceModelName}");
                Console.WriteLine($"当前IP: {camera.f.ChunkActionSourceIP.Value}");
                Console.WriteLine($"固件版本: {camera.f.DeviceFirmwareVersion}");

                trace.Info($"连接成功: {camera.f.DeviceModelName}",
                          "BaumerCamera", "ConnectToCamera", this);
            }
            else
            {
                throw new Exception("相机连接失败");
            }
        }
        catch (Exception ex)
        {
            trace.Error($"连接相机失败: {ex.Message}", "BaumerCamera", "ConnectToCamera", this);
            throw;
        }
    }

    /// <summary>
    /// 配置相机参数
    /// </summary>
    private void ConfigureCamera()
    {
        if (camera == null || !camera.IsConnected)
            return;

        try
        {
            // 检查功能是否可用
            if (camera.HasFeature("ExposureTime") && camera.f.ExposureTime.IsAvailable)
            {
                camera.f.ExposureTime.Value = 5000; // 5ms,10000
                trace.Info($"设置曝光时间: {camera.f.ExposureTime.Value}μs",
                          "BaumerCamera", "ConfigureCamera", this);
            }

            if (camera.HasFeature("Gain") && camera.f.Gain.IsAvailable)
            {
                camera.f.Gain.Value = 1.5;
                trace.Info($"设置增益: {camera.f.Gain.Value}",
                          "BaumerCamera", "ConfigureCamera", this);
            }

            // 设置像素格式
            if (camera.HasFeature("PixelFormat"))
            {
                var pixelFormats = camera.f.PixelFormat.GetEnumValueList();
                foreach (var format in pixelFormats)
                {
                    if (format.Value.IsReadable && format.Value.ValueString == "Mono8")
                    {
                        camera.f.PixelFormat.ValueString = "Mono8";
                        trace.Info($"设置像素格式: Mono8",
                                  "BaumerCamera", "ConfigureCamera", this);
                        break;
                    }
                }
            }

            // 设置触发模式
            if (camera.HasFeature("TriggerMode"))
            {
                camera.f.TriggerMode.Value = TriggerMode.On;
                camera.f.TriggerSource.Value = TriggerSource.Software;
                trace.Info("设置触发模式: 软件触发",
                          "BaumerCamera", "ConfigureCamera", this);
            }

            // 设置缓冲区队列
            camera.ImageBufferCount = 10;
            camera.ImageBufferCycleCount = 10;
            trace.Info($"设置图像缓冲区: {camera.ImageBufferCount}",
                      "BaumerCamera", "ConfigureCamera", this);
        }
        catch (Exception ex)
        {
            trace.Error($"配置相机参数失败: {ex.Message}",
                      "BaumerCamera", "ConfigureCamera", this);
            throw;
        }
    }

    /// <summary>
    /// 注册图像事件回调
    /// </summary>
    private void RegisterImageCallback()
    {
        if (camera == null || !camera.IsConnected)
            return;

        try
        {
            camera.ImageCallback.Handler += ImageCallbackHandler;
            camera.EnableImageCallback();
            trace.Info("图像回调注册成功", "BaumerCamera", "RegisterImageCallback", this);
        }
        catch (Exception ex)
        {
            trace.Error($"注册图像回调失败: {ex.Message}",
                      "BaumerCamera", "RegisterImageCallback", this);
            throw;
        }
    }

    /// <summary>
    /// 图像回调处理
    /// </summary>
    private void ImageCallbackHandler(object sender, ImageEventArgs args)
    {
        try
        {
            if (!args.Image.IsEmpty)
            {
                Console.WriteLine($"回调收到图像: ID={args.Image.ImageIndex}, 大小={args.Image.Size}, " +
                                $"格式={args.Image.PixelFormat}, 时间戳={args.Image.Timestamp}");

                trace.Info($"收到图像: ID={args.Image.ImageIndex}",
                          "BaumerCamera", "ImageCallbackHandler", this);
            }
        }
        catch (Exception ex)
        {
            trace.Error($"图像回调处理错误: {ex.Message}",
                      "BaumerCamera", "ImageCallbackHandler", this);
        }
    }


    // 开始图像采集
    private void StartAcquisition()
    {
        if (camera == null || !camera.IsConnected)
        {
            throw new InvalidOperationException("相机未连接");
        }

        try
        {
            // 设置连续采集模式
            if (camera.HasFeature("AcquisitionMode"))
            {
                camera.f.AcquisitionMode.Value = NeoAPI.AcquisitionMode.Continuous;
            }

            // 开始采集
            if (camera.HasFeature("AcquisitionStart"))
            {
                camera.f.AcquisitionStart.Execute();
                isAcquiring = true;
                trace.Info("开始图像采集", "BaumerCamera", "StartAcquisition", this);
                Console.WriteLine("开始图像采集...");
            }
            else
            {
                throw new NotSupportedException("相机不支持开始采集命令");
            }
        }
        catch (Exception ex)
        {
            trace.Error($"开始采集失败: {ex.Message}",
                      "BaumerCamera", "StartAcquisition", this);
            throw;
        }
    }

    // 停止图像采集
    private void StopAcquisition()
    {
        if (camera != null && isAcquiring)
        {
            try
            {
                if (camera.HasFeature("AcquisitionStop"))
                {
                    camera.f.AcquisitionStop.Execute();
                    isAcquiring = false;
                    trace.Info("停止图像采集", "BaumerCamera", "StopAcquisition", this);
                    Console.WriteLine("已停止图像采集");
                }
            }
            catch (Exception ex)
            {
                trace.Error($"停止采集失败: {ex.Message}",
                          "BaumerCamera", "StopAcquisition", this);
                throw;
            }
        }
    }

    /// <summary>
    /// 触发采集并保存图像
    /// </summary>
    private void TriggerAndSaveImage(int index)
    {
        if (camera == null || !camera.IsConnected || !isGrabbing)
        {
            throw new InvalidOperationException("相机未就绪");
        }

        try
        {
            // 执行软件触发
            if (camera.HasFeature("TriggerSoftware"))
            {
                camera.f.TriggerSoftware.Execute();
                trace.Info($"执行软件触发 #{index}",
                          "BaumerCamera", "TriggerAndSaveImage", this);
            }

            // 获取图像
            using (var image = camera.GetImage(1000))
            {
                if (!image.IsEmpty)
                {
                    // 保存为PNG
                    SaveImage(image, Path.Combine(savePath, "image1.png"));

                    // 保存为JPEG
                    SaveImage(image, Path.Combine(savePath, "image1.jpg"));

                    // 保存为BMP
                    SaveImage(image, Path.Combine(savePath, "image1.bmp"));

                    // 保存为TIFF
                    SaveImage(image, Path.Combine(savePath, "image1.tif"));
                }
            }
        }
        catch (Exception ex)
        {
            trace.Error($"触发采集 #{index} 失败: {ex.Message}",
                      "BaumerCamera", "TriggerAndSaveImage", this);
            throw;
        }
    }

    private void SaveImage(Image image, string filename, string format = "PNG")
    {
        try
        {
            //使用Save方法直接指定格式
            image.Save(filename); // 自动根据扩展名判断格式

            trace.Info($"图像已保存: {filename}", "BaumerCamera", "SaveImage", this);
            Console.WriteLine($"图像已保存: {filename}");
        }
        catch (Exception ex)
        {
            trace.Error($"保存图像失败: {ex.Message}", "BaumerCamera", "SaveImage", this);
            Console.WriteLine($"保存图像失败: {ex.Message}");
        }
    }


    /// <summary>
    /// 断开相机连接
    /// </summary>
    private void DisconnectCamera()
    {
        if (camera != null)
        {
            try
            {
                if (isGrabbing)
                {
                    StopAcquisition();
                }

                // 修正回调取消注册方式
                camera.DisableImageCallback(); // 先禁用回调
                camera.ImageCallback.Handler -= ImageCallbackHandler; // 再移除处理器

                camera.Disconnect();
                camera.Dispose();
                camera = null;
                trace.Info("已断开相机连接", "BaumerCamera", "DisconnectCamera", this);
            }
            catch (Exception ex)
            {
                trace.Error($"断开连接失败: {ex.Message}",
                          "BaumerCamera", "DisconnectCamera", this);
                throw;
            }
        }
    }

    public void Dispose()
    {
        camera?.Dispose();
    }
}